<?php

namespace app\api\controller;

use app\api\validation\Activity;
use app\payment\PayFactory;
use app\services\ActivityService;
use app\services\CallUserService;
use app\services\CoinService;
use app\services\CommentService;
use app\services\CouponService;
use app\services\EmailService;
use app\services\ExchangeService;
use app\services\FollowingService;
use app\services\IdentifyService;
use app\services\LikeService;
use app\services\NameCardService;
use app\services\OrderService;
use app\services\PaymentService;
use app\services\SmsService;
use app\services\SubjectService;
use app\services\TransferService;
use app\services\UserCollectService;
use app\services\UserFansService;
use app\services\UserHistoryService;
use app\services\UserPropertyService;
use app\services\UserService;
use app\services\KeywordService;
use app\services\VIPService;
use EasyWeChat\Factory;
use plugin\admin\app\model\RechargeAmount;
use plugin\admin\app\model\User;
use plugin\admin\app\model\UserCollect;
use plugin\admin\app\model\UserHistory;
use plugin\admin\app\model\UserProfile;
use plugin\admin\app\model\UserPropertyLog;
use plugin\admin\app\model\UserSearchHistory;
use support\Cache;
use support\Db;
use support\Request;
use Webman\Config;
use Webman\RedisQueue\Redis;

class UserController
{
    const FROM_WECHAT = 1;  // 从微信加密数据获取

    const FROM_USER = 2;    // 用户自己填写

    public function profile(Request $request)
    {
        try {
            $data = UserService::profile();

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            echo $e->getMessage() . $e->getTraceAsString();
            return err_rsp($e->getMessage());
        }
    }

    public function transferProperty(Request $request)
    {
        Db::beginTransaction();
        try {
            $to = $request->post('to');

            $toUser = User::where('mobile', $to)->where('status', 0)->first();

            if (!$toUser) {
                throw new \Exception('接收账户不存在');
            }

            if ($toUser['id'] == get_user_id()) {
                throw new \Exception('不能转账给自己');
            }

            $amount = $request->post('amount');

            if (!is_numeric($amount) && $amount <= 0) {
                throw new \Exception('转账金额必须大于0');
            }

            PaymentService::checkPayPassword($request->post('pay_password'));

            UserPropertyService::transfer(get_user_id(), $toUser['id'], $amount);

            Db::commit();
            return ok_rsp('成功');
        } catch (\Exception $e) {
            Db::rollBack();
            echo $e->getMessage() . $e->getTraceAsString();
            return err_rsp($e->getMessage());
        }
    }

    public function transfer(Request $request)
    {
        try {
            $data = $request->post();

            $jobId = TransferService::addJob($data);

            return ok_rsp('成功', ['job_id' => $jobId]);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function transfer2(Request $request)
    {
        try {
            $data = $request->post();

            $jobId = TransferService::addDontNeedTransferJob($data);

            return ok_rsp('成功', ['job_id' => $jobId]);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function getJobMessage(Request $request)
    {
        try {
            $jobId = $request->post('job_id');

            $message = TransferService::getJobMessage($jobId);

            return ok_rsp('成功', $message);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function getJobList(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $length = $request->post('length', 10);

            $data = TransferService::getJobList($page, $length);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function getJob(Request $request)
    {
        try {
            $jobId = $request->post('job_id');

            $data = TransferService::getJob($jobId);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function createJobOrder(Request $request)
    {
        try {
            $jobId = $request->post('job_id');
            $payWay = $request->post('pay_way', PayFactory::WECHAT);
            $payWayType = $request->post('pay_way_type');

            if (PaymentService::needCheckPaymentPassword($payWay)) {
                PaymentService::checkPayPassword($request->post('pay_password'));
            }


            $order = TransferService::createOrder($jobId, $payWay, $payWayType);

            return ok_rsp('成功', $order);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function getDownloadLogList(Request $request)
    {
        try {
            $page = $request->post('page');
            $length = $request->post('length');
            $keyword = $request->post('keyword');

            $data = TransferService::downloadRecordList($page, $length, $keyword);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function vipConfig(Request $request)
    {
        try {
            $data = VIPService::config();

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function vipUpgrade(Request $request)
    {
        try {
            UserService::upgradeToVip();

            return ok_rsp('成功');
        } catch (\Exception $e) {
            return ok_rsp('成功', $e->getMessage());
        }
    }

    public function rechargeAmountList(Request $request)
    {
        try {
            $list = RechargeAmount::all()->toArray();

            return ok_rsp('成功', $list);
        } catch (\Exception $e) {
            return ok_rsp('成功', $e->getMessage());
        }
    }

    public function propertyList(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $length = $request->post('length', 10);
            $type = $request->post('type', 'balance');
            $income = $request->post('income', 0);
            $source = $request->post('source', 0);
//            $month = $request->post('month', null);
            $startMonthDateTime = $request->post('start_time', '1900-01-01');
            $endMonthDateTime = $request->post('end_time', date('Y-m-d'));

            if (empty($startMonthDateTime)) {
                $startMonthDateTime = '1900-01-01';
            }

            if (empty($endMonthDateTime)) {
                $endMonthDateTime = date('Y-m-d');
            }

            if (!in_array($type, [PayFactory::BALANCE, PayFactory::CONTRIBUTION, PayFactory::INTEGRAL, PayFactory::FREEZE_COMMISSION, PayFactory::COMMISSION])) {
                throw new \Exception('不存在的资产类型');
            }

            $timeRange = [];
            $timeRange = [$startMonthDateTime . ' 00:00:00', $endMonthDateTime . ' 23:59:59'];

            $data = UserPropertyService::list($page, $length, $type, $timeRange, $income, $source);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function couponList(Request $request)
    {
        try {
            $status = $request->post('status', 0);
            $list = CouponService::list($status);

            return ok_rsp('成功', $list);
        } catch (\Exception $e) {
            return ok_rsp('成功', $e->getMessage());
        }
    }

    public function beLikeList(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $length = $request->post('length', 10);

            $list = LikeService::beList($page, $length);

            return ok_rsp('成功', $list);
        } catch (\Exception $e) {
            return ok_rsp('成功', $e->getMessage());
        }
    }

    public function callList(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $length = $request->post('length', 10);

            $list = CallUserService::list($page, $length);

            return ok_rsp('成功', $list);
        } catch (\Exception $e) {
            echo $e->getMessage() . $e->getTraceAsString();
            return ok_rsp('成功', $e->getMessage());
        }
    }

    public function coinList(Request $request)
    {
        try {
            $data = CoinService::list();

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return ok_rsp('成功', $e->getMessage());
        }
    }

    public function exchangeToSD(Request $request)
    {
        try {
            $sd = $request->post('amount', 0);

            if ($sd <= 0 || !is_int($sd)) {
                throw new \Exception('请输入正确的股份');
            }

            CoinService::exchangeToSD($sd);

            return ok_rsp('成功');
        } catch (\Exception $e) {
            return ok_rsp('成功', $e->getMessage());
        }

    }


    public function beCommentList(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $length = $request->post('length', 10);

            $list = CommentService::beList($page, $length);

            return ok_rsp('成功', $list);
        } catch (\Exception $e) {
            echo $e->getMessage() . $e->getTraceAsString();
            return ok_rsp('成功', $e->getMessage());
        }
    }

    public function canUseCouponList(Request $request)
    {
        try {
            $price = $request->post('price', 0);
            $list = CouponService::list(0, $price);

            return ok_rsp('成功', $list);
        } catch (\Exception $e) {
            return ok_rsp('成功', $e->getMessage());
        }
    }

    public function checkPaymentPassword(Request $request)
    {
        try {
            PaymentService::checkPayPassword($request->post('pay_password'));

            return ok_rsp('成功', ['err_msg' => '']);
        } catch (\Exception $e) {
            return ok_rsp('成功', ['err_msg' => $e->getMessage()]);
        }
    }

    public function basicProfile(Request $request)
    {
        try {
            $data = UserService::basicProfile($request->post('user_id'));

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function followingList(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $length = $request->post('length', 10);
            $userId = $request->post('user_id', get_user_id());

            $data = FollowingService::list($userId, $page, $length);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function fansList(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $length = $request->post('length', 10);
            $userId = $request->post('user_id', get_user_id());

            $data = UserFansService::followers($page, $length, $userId);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function saveProfile(Request $request)
    {
        try {
            Db::beginTransaction();
            $data = $request->post();
            UserService::saveProfile($data);

            Db::commit();
            return ok_rsp('成功');
        } catch (\Exception $e) {
            Db::rollBack();
            return err_rsp($e->getMessage());
        }

    }

    public function parent(Request $request)
    {
        try {
            $data = UserService::myParent();

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function identifyInfo(Request $request)
    {
        try {
            $data = UserService::identifyInfo();

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function isBindAliPay(Request $request)
    {
        try {
            $data = UserService::isBindAliPay();

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function teamInfo(Request $request)
    {
        try {
            $data = UserService::teamInfo();

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function teamList(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $length = $request->post('length', 10);
            $isIdentify = $request->post('is_identify');

            $data = UserService::teamList($page, $length, $isIdentify);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }


    public function gdToMedal(Request $request)
    {
        Db::beginTransaction();
        try {
            $data = $request->post();
            UserService::gdToMedal($data);

            Db::commit();
            return ok_rsp('成功');
        } catch (\Exception $e) {
            Db::rollBack();
            return err_rsp($e->getMessage());
        }
    }

    public function nameCardBgs(Request $request)
    {
        try {
            $data = NameCardService::bgs();
            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function savePayPassword(Request $request)
    {
        try {
            $data = $request->post();

            if (empty($data['password'])) {
                throw new \Exception('密码不能为空');
            }

            if ($data['password'] != $data['confirm_password']) {
                throw new \Exception('两次密码输入不一致');
            }

            $user = User::where('id', get_user_id())->first()->toArray();

            if (!is_null($user['pay_password'])) {
                if (empty($data['captcha'])) {
                    throw new \Exception('验证码不能为空');
                }

                SmsService::check($user['mobile'], SmsService::CHANGE_PAY_PASSWORD, $data['captcha']);
            }

            UserService::savePayPassword($data);

            return ok_rsp('成功');
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function savePassword(Request $request)
    {
        try {
            $data = $request->post();

            if (!$data['code']) {
                throw new \Exception('验证码不能为空');
            }

            if (empty($data['password']) || empty($data['confirm_password'])) {
                throw new \Exception('密码不能为空');
            }

            if ($data['password'] != $data['confirm_password']) {
                throw new \Exception('两次密码输入不一致');
            }

            $user = User::where('id', get_user_id())->first();
            SmsService::check($user['mobile'], SmsService::CHANGE_PAY_PASSWORD, $data['code']);
            UserService::savePayPassword($data);

            return ok_rsp('成功');
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function friends(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $level = $request->post('level', 0);
            $name = $request->post('name', '');
            $data = UserService::friends($page, 10, $level, $name);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function changePassword(Request $request)
    {
        try {
            $oldPassword = $request->post('old_password');
            $newPassword = $request->post('password');

            return UserService::changePassword($oldPassword, $newPassword);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function levels(Request $request)
    {
        try {
            $data = UserService::levels();

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function openNameCard(Request $request)
    {
        try {
            $payPassword = $request->post('pay_password');
            $payWay = $request->post('pay_way', PayFactory::WECHAT);

            if ($payWay != PayFactory::WECHAT) {
                PaymentService::checkPayPassword($payPassword);
            }

            $result = NameCardService::open([
                'pay_way' => $payWay
            ]);

            return ok_rsp('成功', $result);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function orderCount(Request $request)
    {
        try {
            $data = OrderService::count();

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function collects(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $length = $request->post('length', 10);
            $type = $request->post('type', UserCollect::GOODS);
            $data = UserCollectService::list($page, $length, $type);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function searchHistory(Request $request)
    {
        try {
            $type = $request->post('type', UserSearchHistory::TYPE_GOODS);
            $data = KeywordService::list($type);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function clearHistory(Request $request)
    {
        try {
            $type = $request->post('type', UserSearchHistory::TYPE_GOODS);
            KeywordService::clear($type);

            return ok_rsp('成功');
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function sdList(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $type = $request->post('type', 1);

            $data = UserPropertyService::list($page, 10, PayFactory::SD, $type);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function balanceList(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $type = $request->post('type', 1);

            $data = UserPropertyService::list($page, 10, PayFactory::BALANCE, $type);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function sbList(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $type = $request->post('type', 1);

            switch ($type) {
                default:
                case 1:
                    $data = UserPropertyService::list($page, 10, PayFactory::SB, 0, UserPropertyLog::COIN_GET);
                    break;
                case 2:
                    $data = UserPropertyService::list($page, 10, PayFactory::SD, 1);
                    break;
                case 3:
                    $data = UserPropertyService::list($page, 10, PayFactory::SD, 2);
                    break;
            }

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function validatePhoneToken(Request $request)
    {
        try {
            $captcha = $request->post('captcha');
            $scene = $request->post('scene');

            if (empty($captcha) || empty($scene)) {
                throw new \Exception('验证码或场景不能为空');
            }

            // 生成令牌
            $userId = get_user_id();
            $user = User::find($userId);

            // 验证验证码
            SmsService::check($user['mobile'], SmsService::VALIDATE_PHONE, $captcha);

            $tokenKey = "phone_token_{$userId}_{$scene}";
            $token = bin2hex(random_bytes(16)); // 生成随机令牌
            Cache::set($tokenKey, $token, 1800); // 缓存令牌，时效30分钟

            return ok_rsp('令牌生成成功', ['token' => $token]);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function validateEmailToken(Request $request)
    {
        try {
            $captcha = $request->post('captcha');
            $scene = $request->post('scene');

            if (empty($captcha) || empty($scene)) {
                throw new \Exception('验证码或场景不能为空');
            }

            // 生成令牌
            $userId = get_user_id();
            $user = User::find($userId);

            // 验证验证码
            EmailService::checkCode($user['email'], EmailService::VALIDATE_EMAIL, $captcha);

            $tokenKey = "email_token_{$userId}_{$scene}";
            $token = bin2hex(random_bytes(16)); // 生成随机令牌
            Cache::set($tokenKey, $token, 1800); // 缓存令牌，时效30分钟

            return ok_rsp('令牌生成成功', ['token' => $token]);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function createOrder(Request $request)
    {
        Db::beginTransaction();
        try {
            $payWay = $request->post('pay_way');
            $level = $request->post('level', 1);
            $payWayType = $request->post('pay_way_type', 'h5');

            if (PaymentService::needCheckPaymentPassword($payWay)) {
                PaymentService::checkPayPassword($request->post('pay_password'));
            }

            $order = UserService::createOrder($payWay, $level, $payWayType);

            Db::commit();

            return ok_rsp('成功', $order);
        } catch (\Exception $e) {
            Db::rollBack();
            echo $e->getMessage() . $e->getTraceAsString();
            return err_rsp($e->getMessage());
        }
    }

    public function createApplication(Request $request)
    {
        try {
            UserService::createApplication($request->post());

            return ok_rsp('成功');
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function getApplicationList(Request $request)
    {
        try {
            $page = $request->post('page', 1);
            $length = $request->post('length', 10);

            $data = UserService::getApplicationList($page, $length);

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function setMobile(Request $request)
    {
        $userId = get_user_id();

        $user = User::find($userId);

        try {
            $mobile = $request->post('mobile');
            $code = $request->post('code');
//            $token = $request->post('token');

            if (!$mobile) {
                throw new \Exception('不正确的手机号');
            }

            // 验证令牌
//            $tokenKey = "phone_token_{$userId}_setPhone";
//            $cachedToken = Cache::get($tokenKey);
//            if (!$cachedToken || $cachedToken !== $token) {
//                throw new \Exception('令牌无效或已过期');
//            }

            SmsService::check($mobile, SmsService::CHANGE_PHONE, $code);

            $user->mobile = $mobile;
            $user->save();

            return ok_rsp('设置手机号成功', ['mobile' => format_mobile($user['mobile'])]);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function setEmail(Request $request)
    {
        $userId = get_user_id();

        $user = User::find($userId);

        try {
            $email = $request->post('email');
            $code = $request->post('code');
            $token = $request->post('token');

            if (!$email) {
                throw new \Exception('不正确的邮箱地址');
            }

            // 验证令牌
            $tokenKey = "email_token_{$userId}_setEmail";
            $cachedToken = Cache::get($tokenKey);
            if (!$cachedToken || $cachedToken !== $token) {
                throw new \Exception('令牌无效或已过期');
            }

            EmailService::checkCode($email, EmailService::CHANGE_EMAIL, $code);

            $user->email = $email;
            $user->save();

            return ok_rsp('设置邮箱地址成功', ['email' => format_email($user['email'])]);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    public function exchangeCount(Request $request)
    {
        try {
            $data = OrderService::exchangeCount();

            return ok_rsp('成功', $data);
        } catch (\Exception $e) {
            return err_rsp($e->getMessage());
        }
    }

    protected function getMobileFromWechatEncryptData($request)
    {
        $code = $request->post('code');

        $config = Config::get('wechat');
        $app = Factory::miniProgram($config);

        $res = $app->phone_number->getUserPhoneNumber($code);

        return $res;
    }
}